package com.zhou.service.impl;

import cn.hutool.http.server.HttpServerRequest;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhou.dto.admin.APIAdminDTO;
import com.zhou.dto.admin.AdminUpdateListDTO;
import com.zhou.entity.AdcodeNum;
import com.zhou.entity.Admin;
import com.zhou.mapper.AdminMapper;
import com.zhou.service.AdminService;
import com.zhou.utils.APPApplicationException;
import com.zhou.utils.Base64Util;
import com.zhou.utils.BeanChangeUtils;
import com.zhou.utils.enums.BooleanEnum;
import com.zhou.utils.easyExcel.ExcelHelper;
import com.zhou.utils.gaodei.GetIpConfig;
import com.zhou.utils.gaodei.IPUtil;
import com.zhou.utils.oss.AliOSSUtils;
import com.zhou.utils.token.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.zhou.utils.CommonCast.*;

/**
 * @Description :用户管理
 * @Author : zyy
 * @Date: 2024/6/13  11:41
 */
@Slf4j
@Service("adminService")
public class AdminServiceImpl implements AdminService {
    @Autowired
    private AdminMapper adminMapper;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    //引入封装好的阿里云oss工具类
    @Autowired
    private AliOSSUtils aliOSSUtils;

    @Override
    public Integer code(String phone) {
        //使用工具类随机数生成六位数验证码
        Random random = new Random();
        int i = random.nextInt(999999 - 100000 + 1) + 100000;
        //将验证码存入redis并设置五分钟过期时间
        redisTemplate.opsForValue().set(CODE + phone, i, 3000, TimeUnit.SECONDS);
        return i;
    }

    /**
     * 分页查询
     *
     * @param page      1
     * @param pageSize  10
     * @param isDelFlag
     * @param isStatus
     * @return
     */
    @Override
    public List<Admin> getList(Integer page, Integer pageSize, Integer isDelFlag, Integer isStatus) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        Page<Admin> adminPage = new Page<>(page, pageSize);
        if (BeanChangeUtils.isNotEmpty(isDelFlag)) {
            wrapper.eq(Admin::getIsDelFlag, isDelFlag);
        }
        if (BeanChangeUtils.isNotEmpty(isStatus)) {
            wrapper.eq(Admin::getIsStatus, isStatus);
        }
        return adminMapper.selectPage(adminPage, wrapper).getRecords();
    }

    /**
     * 修改用户为管理员
     *
     * @param id
     * @return
     */
    @Override
    public String update(String id) {
        //先查看有没有这个用户
        Admin admin = adminMapper.selectById(id);
        if (BeanChangeUtils.isEmpty(admin)) {
            throw new APPApplicationException("没有这个用户");
        }
        if (admin.getIsAdmin().equals(BooleanEnum.TURE.getResultValue())) {
            //已经是管理员
            throw new APPApplicationException("已经是管理员");
        } else {
            //不是管理员
            admin.setIsAdmin(BooleanEnum.TURE.getResultValue());
            adminMapper.updateById(admin);
        }
        return "修改成功";
    }

    /**
     * 用户登录
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    public String login(String phone, Integer code, HttpServletRequest request) throws APPApplicationException {
        if (BeanChangeUtils.isEmpty(phone) || BeanChangeUtils.isEmpty(code)) {
            throw new APPApplicationException("手机号或验证码不能为空");
        }
        //根据http请求获取当前登录的用户ip
        String clientIP = IPUtil.getClientIP(request);
        //根据ip获取到当前的用户地址
        String configIp = GetIpConfig.getConfigIp(clientIP);
        Object parse = JSONObject.parse(configIp);
        Map<String, Object> address = GetIpConfig.getAddress(parse);
        if (BeanChangeUtils.isEmpty(address)) {
            throw new APPApplicationException("ip地址解析错误，请重新登录，要是还不行请联系管理员");
        }
        //获取到存在redis的code进行判断
        Object o = redisTemplate.opsForValue().get(CODE + phone);
        if (BeanChangeUtils.isEmpty(o) || !o.equals(code)) {
            throw new APPApplicationException("验证码无效请重试");
        } else {
            //验证码正确进行下一步
            //确定手机号有没有注册
            LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Admin::getPhone, phone);
            Admin admin = adminMapper.selectOne(wrapper);
            String token = "";
            Map<String, Object> map = new HashMap<>();
            map.put("phone", phone);
            if (BeanChangeUtils.isEmpty(admin)) {
                //没有注册就是新增
                Admin adminOne = new Admin();
                adminOne.setId(UUID.randomUUID().toString());
                adminOne.setPhone(phone);
                adminOne.setCreateTime(new Date());
                byte[] bytes = DEFAULT_PASSWORD.getBytes();
                String base64 = null;
                try {
                    base64 = Base64Util.encryptBASE64(bytes);
                } catch (Exception e) {
                    throw new APPApplicationException("类型转换出问题了，请重试");
                }
                adminOne.setPassword(base64);
                adminOne.setAddress(address.get("province").toString());
                adminOne.setAdcode(address.get("adcode").toString());
                int insert = adminMapper.insert(adminOne);
                if (BooleanEnum.FLASE.getResultValue().equals(insert)) {
                    throw new APPApplicationException("注册失败");
                }
                map.put("admin", adminOne);
                token = JWTUtils.sign(adminOne.getPhone(), map);
                //存进redis设置一天过期时间
                redisTemplate.opsForValue().set(USER_KEY + adminOne.getId(), JSONObject.toJSONString(adminOne), 30, TimeUnit.DAYS);
            } else {
                //需要修改登录地址
                admin.setAddress(address.get("province").toString());
                admin.setAdcode(address.get("adcode").toString());
                adminMapper.updateById(admin);
                //注册过的就是直接登录
                token = JWTUtils.sign(admin.getPhone(), map);
                //存进redis设置一天过期时间
                redisTemplate.opsForValue().set(USER_KEY + admin.getId(), JSONObject.toJSONString(admin), 30, TimeUnit.DAYS);
            }
            //登录成功需要提前将验证码删除
            redisTemplate.delete(CODE + phone);
            return token;
        }
    }

    /**
     * 用户密码登录
     *
     * @param phone    手机号
     * @param password 密码
     * @return
     */
    @Override
    public String loginPassword(String phone, String password, HttpServletRequest request) {
        Admin admin = adminMapper.selectOne(new LambdaQueryWrapper<Admin>().eq(Admin::getPhone, phone));
        if (BeanChangeUtils.isEmpty(admin)) {
            throw new APPApplicationException("该账号还没注册过，请先去注册后在登录");
        }
        byte[] bytes = null;
        try {
            //获得解密后的密码
            bytes = Base64Util.decryBASE64(admin.getPassword());
            byte[] bytes1 = password.getBytes();
            //两个byte数组进行比较
            if (!Arrays.equals(bytes, bytes1)) {
                return "密码错误";
            }
        } catch (Exception e) {
            throw new APPApplicationException(e.getMessage());
        }
        Map<String, Object> map = new HashMap<>();
        map.put("admin", admin);
        //密码正确就是直接登录
        String token = JWTUtils.sign(admin.getPhone(), map);
        //存进redis设置一天过期时间
        redisTemplate.opsForValue().set(USER_KEY + admin.getId(), JSONObject.toJSONString(admin), 1, TimeUnit.DAYS);
        //根据http请求获取当前登录的用户ip
        String clientIP = IPUtil.getClientIP(request);
        //根据ip获取到当前的用户地址
        String configIp = GetIpConfig.getConfigIp(clientIP);
        Object parse = JSONObject.parse(configIp);
        Map<String, Object> address = GetIpConfig.getAddress(parse);
        if (BeanChangeUtils.isEmpty(address)) {
            throw new APPApplicationException("ip地址解析错误，请重新登录，要是还不行请联系管理员");
        }
        admin.setAddress(address.get("province").toString());
        admin.setAdcode(address.get("adcode").toString());
        adminMapper.updateById(admin);
        return token;
    }


    /**
     * 批量修改
     *
     * @param
     * @return
     */
    @Override
    public String adminUpdates(AdminUpdateListDTO adminUpdateListDTO) {
        if (BeanChangeUtils.isEmpty(adminUpdateListDTO)) {
            throw new APPApplicationException("请选择要修改数据");
        }
        //通过id集合查询用户集合
        List<Admin> admins = adminMapper.selectBatchIds(adminUpdateListDTO.getIds());
        if (BeanChangeUtils.isEmpty(admins)) {
            throw new APPApplicationException("没有查到所选用户信息，请刷新页面重试");
        }
        //状态不为空就修改状态
        if (BeanChangeUtils.isNotEmpty(adminUpdateListDTO.getStatus())) {
            for (Admin admin : admins) {
                //如果相等就不用修改直接跳过
                if (adminUpdateListDTO.getStatus().equals(admin.getIsStatus())) {
                    continue;
                }
                if (adminUpdateListDTO.getStatus() == YES) {
                    admin.setIsStatus(BooleanEnum.TURE.getResultValue());
                } else {
                    admin.setIsStatus(BooleanEnum.FLASE.getResultValue());
                }
                adminMapper.updateById(admin);
            }
        }
        //注销不为空就修改注销状态
        if (BeanChangeUtils.isNotEmpty(adminUpdateListDTO.getDelFlag())) {
            for (Admin admin : admins) {
                //如果相等就不用修改直接跳过
                if (adminUpdateListDTO.getDelFlag().equals(admin.getIsDelFlag())) {
                    continue;
                }
                if (adminUpdateListDTO.getDelFlag() == YES) {
                    admin.setIsDelFlag(BooleanEnum.TURE.getResultValue());
                } else {
                    admin.setIsDelFlag(BooleanEnum.FLASE.getResultValue());
                }
                adminMapper.updateById(admin);
            }
        }
        return "修改成功";
    }

    /**
     * 导出excel
     *
     * @param isStatus  是否停用
     * @param isDelFlag 是否注销
     * @return
     */
    @Override
    public void export(Integer isStatus, Integer isDelFlag) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        if (BeanChangeUtils.isNotEmpty(isStatus)) {
            wrapper.eq(Admin::getIsStatus, isStatus);
        }
        if (BeanChangeUtils.isNotEmpty(isDelFlag)) {
            wrapper.eq(Admin::getIsDelFlag, isDelFlag);
        }
        List<Admin> admins = adminMapper.selectList(wrapper);
        if (BeanChangeUtils.isNotEmpty(admins)) {
            ExcelHelper.writeExcel(EXCEL_EXPORT_URL, Admin.class, "用户信息", admins);
        }
    }

    /**
     * 导出excel
     * @param file
     */
    @Override
    public void input(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),AdcodeNum.class,new PageReadListener<AdcodeNum>(nums -> {
                log.info("解析到数据{}条",nums.size());
                    adminMapper.inputAdcode(nums);
            }));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("导入成功");

    }
    /**      ---------------------------------------------小程序---------------------------------------------            */
    /**
     * 用户完善信息
     *
     * @param adminDTO
     * @return
     */
    @Override
    public String apiUpdateUser(APIAdminDTO adminDTO) {
        //查询用户是否存在或者否被注销
        Admin admin = adminMapper.selectOne(new LambdaQueryWrapper<Admin>().eq(Admin::getPhone, adminDTO.getPhone()));
        if (BeanChangeUtils.isEmpty(admin)) {
            throw new APPApplicationException("用户不存在，请重试");
        }
        admin.setName(adminDTO.getName());
        admin.setUpdateTime(new Date());
        admin.setGender(adminDTO.getGender());
        admin.setIdCard(adminDTO.getIdCard());
        if (BeanChangeUtils.isNotEmpty(adminDTO.getAvatar())) {
            //这里需要将头像上传到oss上面
            admin.setAvatar(adminDTO.getAvatar());
        }
        if (BeanChangeUtils.isNotEmpty(adminDTO.getAddress())) {
            admin.setAddress(adminDTO.getAddress());
        }
        if (BeanChangeUtils.isNotEmpty(adminDTO.getSalary())) {
            admin.setSalary(adminDTO.getSalary());
        }
        if (BeanChangeUtils.isNotEmpty(adminDTO.getQualification())) {
            admin.setQualification(adminDTO.getQualification());
        }
        if (BeanChangeUtils.isNotEmpty(adminDTO.getHobby())) {
            admin.setHobby(adminDTO.getHobby());
        }
        if (BeanChangeUtils.isNotEmpty(adminDTO.getWxId())) {
            admin.setWxId(adminDTO.getWxId());
        }
        if (BeanChangeUtils.isNotEmpty(adminDTO.getNickName())) {
            admin.setNickName(adminDTO.getNickName());
        }
        int i = adminMapper.updateById(admin);
        if (BooleanEnum.FLASE.getResultValue().equals(i)) {
            return "修改失败";
        } else {
            return "修改成功";
        }

    }


    /**
     * 登出
     *
     * @param adminId 用户id
     * @return 登出结果
     */
    @Override
    public String logOut(String adminId) {
        if (BeanChangeUtils.isEmpty(adminId)) {
            return "手机号不能为空";
        }
        Object o = redisTemplate.opsForValue().get(USER_KEY + adminId);
        if (BeanChangeUtils.isNotEmpty(o)) {
            redisTemplate.delete(USER_KEY + adminId);
            return "登出成功";
        }
        return "登出失败";
    }

}
